package ihm;

//Import the basic graphics classes.  
// The problem here is that we read the image with OpenCV into a Mat object.  
// But OpenCV for java doesn't have the method "imshow", so, we got to use  
// java for that (drawImage) that uses Image or BufferedImage.  
// So, how to go from one the other... Here is the way...  
import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.highgui.Highgui;
import org.opencv.highgui.VideoCapture;

public class VideoPanel2 extends JPanel implements Runnable {

	private static final long serialVersionUID = 1L;
	private BufferedImage image;
	private VideoCapture capture;
	private boolean stop = false;
	

	// Create a constructor method
	public VideoPanel2() {
		super();
		System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
		capture = new VideoCapture(0);
	}

	private BufferedImage getimage() {
		return image;
	}

	public void setimage(BufferedImage newimage) {
		image = newimage;
		return;
	}

	/**
	 * Converts/writes a Mat into a BufferedImage.
	 * 
	 * @param matrix
	 *            Mat of type CV_8UC3 or CV_8UC1
	 * @return BufferedImage of type TYPE_3BYTE_BGR or TYPE_BYTE_GRAY
	 */

	public static BufferedImage matToBufferedImage(Mat matrix) {
		int cols = matrix.cols();
		int rows = matrix.rows();
		int elemSize = (int) matrix.elemSize();
		byte[] data = new byte[cols * rows * elemSize];
		int type;
		matrix.get(0, 0, data);

		switch (matrix.channels()) {
		case 1:
			type = BufferedImage.TYPE_BYTE_GRAY;
			break;
		case 3:
			type = BufferedImage.TYPE_3BYTE_BGR;
			// bgr to rgb
			byte b;
			for (int i = 0; i < data.length; i = i + 3) {
				b = data[i];
				data[i] = data[i + 2];
				data[i + 2] = b;
			}
			break;
		default:
			return null;
		}

		BufferedImage image2 = new BufferedImage(cols, rows, type);
		image2.getRaster().setDataElements(0, 0, cols, rows, data);
		return image2;
	}

	public void paintComponent(Graphics g) {
		BufferedImage temp = getimage();
		try {
			g.drawImage(temp, 10, 10, temp.getWidth(), temp.getHeight(), this);
		} catch (NullPointerException e) {

		}
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		Mat webcam_image = new Mat();
		BufferedImage temp;
		if (capture.isOpened()) {
			while (!stop) {
				capture.read(webcam_image);
				if (!webcam_image.empty()) {
					this.setSize(webcam_image.width() + 20,
							webcam_image.height() + 40);
					temp = matToBufferedImage(webcam_image);
					this.setimage(temp);
					this.invalidate();
					this.validate();
					this.repaint();
				} else {
					System.out.println(" --(!) No captured frame -- Break!");
					break;
				}
			}
		}
	}

	public VideoCapture getCapture() {
		return capture;
	}

	public void setCapture(VideoCapture capture) {
		this.capture = capture;
	}
	
	public void AfficherImage(Mat image){
		//affiche une image 
		BufferedImage temp;
		temp = matToBufferedImage(image);
		this.setimage(temp);
		this.invalidate();
		this.validate();
		this.repaint();
	}

	public Mat capture() {
		//appel lors de la prise de photo
		if (!capture.isOpened()) {
			System.out.println("did not connect  to camera");
		} else
			System.out.println("found camera" + capture.toString());
		Mat frame = new Mat();
		capture.retrieve(frame);
		
		//Highgui.imwrite("image/snapshot.png", frame);
		return frame;
	}

	public void stop() {
		stop = true;
	}
	public void play(){
		stop = false;
		new Thread(this).start();
	}
}